package com.hhkj.study.admin.resource.common;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.hhkj.study.admin.resource.entity.ResourceCourseDoc;
import com.hhkj.study.admin.resource.entity.ResourceCourseVideo;
import com.hhkj.study.admin.resource.entity.ResourceQuestionBank;
import com.hhkj.study.admin.resource.excel.BaseExcelRes;
import com.hhkj.study.admin.resource.service.extend.ResourceCourseDocExtendService;
import com.hhkj.study.admin.resource.service.extend.ResourceCourseVideoExtendService;
import com.hhkj.study.admin.resource.service.extend.ResourceQuestionBankExtendService;
import com.hhkj.study.admin.teacher.entity.Teacher;
import com.hhkj.study.admin.teacher.service.extend.TeacherExtendService;
import com.hhkj.study.common.model.res.ExcelImportResultRes;
import com.ruoyi.common.exception.FieldValueBusinessException;
import com.ruoyi.common.utils.bean.BeanValidators;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;

/**
 * @Author luowu
 * @Date 2024/9/24 涵 11:39:04
 */
@Component
public class CommonValidateHandler {

    @Resource
    private TeacherExtendService teacherExtendService;

    @Resource
    private ResourceCourseDocExtendService docExtendService;

    @Resource
    private ResourceCourseVideoExtendService videoExtendService;

    @Resource
    private ResourceQuestionBankExtendService questionBankExtendService;

    /** 视频类型中回放值 */
    private static final String VIDEO_PLAY_BACK_VALUE = "回放";

    /**
     * 校验通用参数 主要针对于资源
     * @return
     */
    public ExcelImportResultRes validate(List<? extends BaseExcelRes> baseExcelResList, BiFunction<String, Long, Boolean> function){
        ExcelImportResultRes excelImportResultRes = new ExcelImportResultRes();
        List<ExcelImportResultRes.ResultInfo> resultInfoList = excelImportResultRes.getErrorList();
        // 储存表中重复的名称后续判断重复
        List<String> repeatNameList = Lists.newArrayList();
        // 针对导入回放中重复的视频名
        List<String> repeatVideoNameList = Lists.newArrayList();
        for (BaseExcelRes baseExcelRes : baseExcelResList) {
            try {
                BeanValidators.validate(baseExcelRes);
            } catch (ConstraintViolationException e) {
                resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), e.getMessage()));
            }
            if (CollectionUtil.isNotEmpty(resultInfoList)) {
                excelImportResultRes.setErrorAmount(resultInfoList.size());
                return excelImportResultRes;
            }
            if (StrUtil.isNotBlank(baseExcelRes.getName())) {
                String nameCourseType = StrUtil.format("{}#{}", baseExcelRes.getName(), baseExcelRes.getResourceCourseType());
                if (repeatNameList.contains(nameCourseType)) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), baseExcelRes.getName() + " 表中该名称已存在"));
                }
                if (Boolean.TRUE.equals(function.apply(baseExcelRes.getName(), baseExcelRes.getResourceCourseType()))) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), "该课程类型下 " + baseExcelRes.getName() + " 名称已存在"));
                }

                repeatNameList.add(nameCourseType);
            }
            if (StrUtil.isNotBlank(baseExcelRes.getLiveName())) {
                String liveNameCourseType = StrUtil.format("{}#{}", baseExcelRes.getLiveName(), baseExcelRes.getResourceCourseType());
                if (repeatVideoNameList.contains(liveNameCourseType)) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), "该课程类型下 " + baseExcelRes.getLiveName() + " 表格中该名称已存在"));
                }
                if (Boolean.FALSE.equals(function.apply(baseExcelRes.getLiveName(), baseExcelRes.getResourceCourseType()))) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), "该课程类型下 " + baseExcelRes.getLiveName() + " 直播不存在"));
                }
                repeatVideoNameList.add(liveNameCourseType);
            }
            if (StrUtil.isNotBlank(baseExcelRes.getTeacherName())) {
                Teacher teacher = teacherExtendService.getByName(baseExcelRes.getTeacherName());
                if (ObjectUtil.isNull(teacher)) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), baseExcelRes.getTeacherName() + " 讲师不存在"));
                } else {
                    baseExcelRes.setTeacherId(teacher.getId());
                }
            }
            if (StrUtil.isNotBlank(baseExcelRes.getDocName())) {
                ResourceCourseDoc courseDoc = docExtendService.getByNameCourseType(baseExcelRes.getDocName(), baseExcelRes.getResourceCourseType());
                if (ObjectUtil.isNull(courseDoc)) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), "该课程类型下 " + baseExcelRes.getDocName() + " 资料不存在"));
                } else {
                    baseExcelRes.setDocId(courseDoc.getId());
                }
            }

            // 针对于导入回放到视频中需要额外判断是否视频中已有相同名称
            if (StrUtil.isNotBlank(baseExcelRes.getVideoName())) {
                ResourceCourseVideo courseVideo = videoExtendService.getByNameCourseType(baseExcelRes.getVideoName(), baseExcelRes.getResourceCourseType());
                if (ObjectUtil.isNotNull(courseVideo)) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), "该课程类型下即将导入到视频数据中的 " + baseExcelRes.getVideoName() + VIDEO_PLAY_BACK_VALUE + " 视频已存在"));
                }
            }

            if (StrUtil.isNotBlank(baseExcelRes.getBankName())) {
                ResourceQuestionBank questionBank = questionBankExtendService.getByNameCourseType(baseExcelRes.getBankName(), baseExcelRes.getResourceCourseType());
                if (ObjectUtil.isNull(questionBank)) {
                    resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), "该课程类型下 " + baseExcelRes.getBankName() + " 题库不存在"));
                } else {
                    baseExcelRes.setBankId(questionBank.getId());
                }
            }
        }
        if (CollectionUtil.isNotEmpty(resultInfoList)) {
            excelImportResultRes.setErrorAmount(resultInfoList.size());
        } else {
            excelImportResultRes.setSuccessAmount(baseExcelResList.size());
        }
        return excelImportResultRes;
    }

    /**
     * 通用字段校验+业务校验
     * 针对业务中需要验证的参数校验
     * @param baseExcelResList
     * @param consumer
     * @return
     */
    public ExcelImportResultRes commonValidate(List<? extends BaseExcelRes> baseExcelResList, Consumer<? super BaseExcelRes> consumer){

        ExcelImportResultRes excelImportResultRes = new ExcelImportResultRes();
        List<ExcelImportResultRes.ResultInfo> resultInfoList = excelImportResultRes.getErrorList();
        for (BaseExcelRes baseExcelRes : baseExcelResList) {
            try {
                BeanValidators.validate(baseExcelRes);
            } catch (ConstraintViolationException e) {
                resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), e.getMessage()));
            }

            try {
                consumer.accept(baseExcelRes);
            } catch (FieldValueBusinessException e) {
                resultInfoList.add(new ExcelImportResultRes.ResultInfo(baseExcelRes.getIndexNum(), e.getMessage()));
            }
        }

        if (CollectionUtil.isNotEmpty(resultInfoList)) {
            excelImportResultRes.setErrorAmount(resultInfoList.size());
        } else {
            excelImportResultRes.setSuccessAmount(baseExcelResList.size());
        }
        return excelImportResultRes;
    }
}
